package com.magiccompass.alipay.barcode.responsehandler;

import org.w3c.dom.Document;

import com.magiccompass.alipay.barcode.constants.BusinessLogicConstants;
import com.magiccompass.alipay.barcode.entity.AlipayBarcodePaymentRequest;
import com.magiccompass.alipay.barcode.entity.AlipayBarcodePaymentResponse;
import com.magiccompass.alipay.barcode.entity.MerchantTransaction;
import com.magiccompass.alipay.barcode.model.AlipayBarcodeAllResponseAJAXModel;
import com.magiccompass.alipay.barcode.model.AlipayBarcodePaymentResponseModel;
import com.magiccompass.alipay.barcode.service.AlipayBarcodeService;
import com.magiccompass.alipay.barcode.util.AlipayBarcodeResponseUtil;
import com.magiccompass.alipay.barcode.util.DateTimeUtil;
import com.magiccompass.alipay.barcode.util.DecimalUtil;
import com.magiccompass.alipay.barcode.util.XmlUtil;

public class PaymentResponseHandler {
	public static AlipayBarcodeAllResponseAJAXModel handleResponse(String response,
			AlipayBarcodePaymentRequest abpr,AlipayBarcodeService alipayBarcodeService){
		AlipayBarcodePaymentResponseModel abprm = getResponseResult(response);
		AlipayBarcodeAllResponseAJAXModel ajaxModel = handleResultFromResultCode(abprm,abpr,alipayBarcodeService);
		return ajaxModel;
	}	
	
	private static AlipayBarcodePaymentResponseModel getResponseResult(String response){
		Document xmlDoc = XmlUtil.makeXmlDocumentFromString(response);
		
		AlipayBarcodePaymentResponseModel abpr = new AlipayBarcodePaymentResponseModel();
		
		String responseIsSuccess = xmlDoc.getElementsByTagName("is_success").item(0).getTextContent();
		String sign = xmlDoc.getElementsByTagName("sign").item(0)==null?null:xmlDoc.getElementsByTagName("sign").item(0).getTextContent();
		String signType = xmlDoc.getElementsByTagName("sign_type").item(0)==null?null:xmlDoc.getElementsByTagName("sign_type").item(0).getTextContent();
		
		abpr.setIsSuccess(responseIsSuccess);
		abpr.setSign(sign);
		abpr.setSignType(signType);
		
		boolean hasSuccessResponseWithResult = false;
		
		if("T".equals(abpr.getIsSuccess())){
			String responseResultCode = xmlDoc.getElementsByTagName("result_code").item(0).getTextContent();
			abpr.setResultCode(responseResultCode);
			if("SUCCESS".equals(responseResultCode)){
				String alipayTransId = xmlDoc.getElementsByTagName("alipay_trans_id").item(0)==null?null:xmlDoc.getElementsByTagName("alipay_trans_id").item(0).getTextContent();
				String partnerTransId = xmlDoc.getElementsByTagName("partner_trans_id").item(0)==null?null:xmlDoc.getElementsByTagName("partner_trans_id").item(0).getTextContent();
				String alipayBuyerLoginId = xmlDoc.getElementsByTagName("alipay_buyer_login_id")==null?null:xmlDoc.getElementsByTagName("alipay_buyer_login_id").item(0).getTextContent();
				String alipayPayTime = xmlDoc.getElementsByTagName("alipay_pay_time").item(0)==null?null:xmlDoc.getElementsByTagName("alipay_pay_time").item(0).getTextContent();
				String exchangeRate = xmlDoc.getElementsByTagName("exchange_rate").item(0)==null?null:xmlDoc.getElementsByTagName("exchange_rate").item(0).getTextContent();
				String transAmount = xmlDoc.getElementsByTagName("trans_amount").item(0)==null?null:xmlDoc.getElementsByTagName("trans_amount").item(0).getTextContent();
				String transAmountCNY = xmlDoc.getElementsByTagName("trans_amount_CNY").item(0)==null?null:xmlDoc.getElementsByTagName("trans_amount_CNY").item(0).getTextContent();
				
				String alipayBuyerUserId = xmlDoc.getElementsByTagName("alipay_buyer_user_id").item(0)==null?null:xmlDoc.getElementsByTagName("alipay_buyer_user_id").item(0).getTextContent();
				String currency = xmlDoc.getElementsByTagName("currency").item(0)==null?null:xmlDoc.getElementsByTagName("currency").item(0).getTextContent();
				
				abpr.setAlipayBuyerLoginId(alipayBuyerLoginId);
				abpr.setAlipayBuyerUserId(alipayBuyerUserId);
				abpr.setPartnerTransId(partnerTransId);
				abpr.setAlipayTransId(alipayTransId);
				abpr.setAlipayPayTime(alipayPayTime);
				abpr.setCurrency(currency);
				abpr.setTransAmount(DecimalUtil.createBigDecimalFromString(transAmount));
				abpr.setExchangeRate(DecimalUtil.createBigDecimalFromString(exchangeRate));
				abpr.setTransAmountCNY(DecimalUtil.createBigDecimalFromString(transAmountCNY));
				
				hasSuccessResponseWithResult = true;
			}else if("FAILED".equals(responseResultCode)){
				String error = xmlDoc.getElementsByTagName("error").item(0).getTextContent();
				abpr.setError(error);	
			}else if("UNKNOW".equals(responseResultCode)){
				String error = xmlDoc.getElementsByTagName("error").item(0)==null?null:xmlDoc.getElementsByTagName("error").item(0).getTextContent();
				abpr.setError(error);
			}else{
				abpr.setError("UNEXPECTED EXCEPTION");
			}
		}else if("F".equals(abpr.getIsSuccess())){
			abpr.setResultCode("-1");
			String error = xmlDoc.getElementsByTagName("error").item(0)==null?null:xmlDoc.getElementsByTagName("error").item(0).getTextContent();
			abpr.setError(error);
		}else{
			abpr.setResultCode("-2"); // ALIPAY response neither "T" nor "F"
			abpr.setError("UNEXPECTED EXCEPTION!");
		}
		if(!hasSuccessResponseWithResult){
			// follow column are mandatory, so I need give some default value
			abpr.setAlipayBuyerLoginId("-1");
			abpr.setAlipayBuyerUserId("-1");
			abpr.setPartnerTransId("-1");
			abpr.setAlipayTransId("-1");
			abpr.setAlipayPayTime(DateTimeUtil.getCurrentDateYYYYMMDDHH24MISSString());
			abpr.setCurrency("-1");
			abpr.setTransAmount(DecimalUtil.createBigDecimalFromString("-1"));
		}
		return abpr;
	}
	
	private static AlipayBarcodeAllResponseAJAXModel handleResultFromResultCode(
			AlipayBarcodePaymentResponseModel abprm, AlipayBarcodePaymentRequest abpreq, AlipayBarcodeService alipayBarcodeService){
		
		AlipayBarcodeAllResponseAJAXModel abpram = new AlipayBarcodeAllResponseAJAXModel();

		MerchantTransaction mt = abpreq.getMerchantTransaction();
		if("T".equals(abprm.getIsSuccess())){  // request success accept by ALIPAY
			String resultCode = abprm.getResultCode();
			if("SUCCESS".equals(resultCode)){
				abpreq.setStatus("S");
				mt.setStatus("S");
				abpram.setResponseResultCode(resultCode);
				abpram.setResponseResultReason("Please continue.");
			}else if("FAILED".equals(resultCode)){
				abpreq.setStatus("F");
				mt.setStatus("F"); // // if payment failed means this transaction failed, no more can be done
				abpram.setResponseResultCode(resultCode);
				abpram.setResponseResultReason(abprm.getError());
			}else if("UNKNOW".equals(resultCode)){
				abpreq.setStatus("U");
				//TODO need reverse payment(offline) or query(online) 
				mt.setStatus("U");
				// 2016-03-22 confirm: offline mode
				abpram.setResponseResultCode(resultCode);
				abpram.setResponseResultReason(abprm.getError());				
			}	
		}else if("F".equals(abprm.getIsSuccess())){ // request failed accept by ALIPAY, maybe parameter error
			abpreq.setStatus("D");
			mt.setStatus("D");
			abpram.setResponseResultCode("ERROR");
			abpram.setResponseResultReason(abprm.getError());
		}else{
			abpreq.setStatus("D");
			mt.setStatus("D");
			abpram.setResponseResultCode("UNEXPECTED");
			abpram.setResponseResultReason("Unexpected error happened. Please contact support.");
		}
		mt.setUpdateby(BusinessLogicConstants.SYSTEM_CREATOR_ID);
		mt.setUpdateTime(DateTimeUtil.getCurrentTimestamp());
		abpreq.setMerchantTransaction(mt);
		abpreq.setFinalizedTime(DateTimeUtil.getCurrentTimestamp());
		abpreq.setUpdateby(BusinessLogicConstants.SYSTEM_CREATOR_ID);
		abpreq.setUpdateTime(DateTimeUtil.getCurrentTimestamp());
		alipayBarcodeService.save(abpreq);
		
		AlipayBarcodePaymentResponse abpr = AlipayBarcodeResponseUtil.createAlipayBarcodePaymentReponseEntityFromModelAndRequest(abprm, abpreq);
		alipayBarcodeService.save(abpr);
		
		return abpram;
	}
	
	public static AlipayBarcodeAllResponseAJAXModel handleResultFromQueryStatus(
			String queryStatus, AlipayBarcodePaymentRequest abpreq, AlipayBarcodeService alipayBarcodeService){		
		AlipayBarcodeAllResponseAJAXModel abpram = new AlipayBarcodeAllResponseAJAXModel();
		MerchantTransaction mt = abpreq.getMerchantTransaction();
		if("S".equals(queryStatus)){
			abpreq.setStatus("S");
			mt.setStatus("S");
			abpram.setResponseResultCode("SUCCESS");
			abpram.setResponseResultReason("Please continue.");
		}else if("F".equals(queryStatus)){  
			mt.setStatus("F"); // // if payment failed means this transaction failed, no more can be done
			abpram.setResponseResultCode("FAILED");
			abpram.setResponseResultReason("This transaction payment is failed.");
		}else if("X".equals(queryStatus)){
			abpram.setResponseResultCode("UNEXPECTED");
			abpram.setResponseResultReason("Unexpected error happened. This transaction auto reverse failed. Please reverse it manually.");
		}else{
			mt.setStatus("D");
			abpram.setResponseResultCode("UNEXPECTED");
			abpram.setResponseResultReason("Unexpected error happened. error code from Alipay is:"+queryStatus+".This transaction has been deleted. Please contact support.");
		}
		mt.setUpdateby(BusinessLogicConstants.SYSTEM_CREATOR_ID);
		mt.setUpdateTime(DateTimeUtil.getCurrentTimestamp());
		alipayBarcodeService.save(mt);
		
		return abpram;
	}
	
	public static void main(String[] args){
		AlipayBarcodePaymentResponseModel abprm = getResponseResult(RESULT_PAYMENT_SUCCESS_4_TEST);
		System.out.println(abprm);

	}
	
	public static final String RESULT_PAYMENT_SUCCESS_4_TEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><alipay><is_success>T</is_success><request><param name=\"trans_create_time\">20160323103315</param><param name=\"identity_code_type\">barcode</param><param name=\"alipay_seller_id\">2088021966645500</param><param name=\"sign_type\">RSA</param><param name=\"trans_amount\">61.87</param><param name=\"trans_name\">PAYMENT_BY_ALIPAY_BARCODE</param><param name=\"partner_trans_id\">1475</param><param name=\"buyer_identity_code\">123456789012345678</param><param name=\"currency\">AUD</param><param name=\"sign\">T0cPCjvrtoOMgMx5kztMXJj1k7BquXSszD0yXK9IoGYt/PwDYK6UUZiMWN41QUpjGZD1uDMKJWhtRMfw7Zwsd5/ieQ3ODB/OMy6FN6zCrztUr4v0rpPvyCRTI9DWR8iVqPay64lT3335AbvqD3wp2zqw97xbQ9e2ykmH/7VVrlQ=</param><param name=\"_input_charset\">UTF-8</param><param name=\"biz_product\">OVERSEAS_MBARCODE_PAY</param><param name=\"service\">alipay.acquire.overseas.spot.pay</param><param name=\"partner\">2088021966645500</param></request><response><alipay><alipay_trans_id>2011091703338463</alipay_trans_id><partner_trans_id>1475</partner_trans_id><alipay_buyer_user_id>2088102130896433</alipay_buyer_user_id><alipay_buyer_login_id>cao***@126.com</alipay_buyer_login_id><alipay_pay_time>20131120155823</alipay_pay_time><exchange_rate>6.0939</exchange_rate><currency>AUD</currency><trans_amount>39.25</trans_amount><trans_amount_CNY>239.19</trans_amount_CNY><result_code>SUCCESS</result_code></alipay></response><sign>D/UTFJt5yh3rxNXSE5botyzpyv9vDe/QbJpLgJ98j3j9HtGcVHpUtPyFr/3ZuVt3VFJ4XI9v41/wqe1qBEeTjffg4hmXOWF1nc8+ePfZNi883Qgl7a4d3hzcXzr9j1lsK33cJeruLEBeQOiu7umd3jPBHdBSBx9qt7DbeLgbtKM=</sign><sign_type>RSA</sign_type></alipay>";
	public static final String RESULT_PAYMENT_FAILED_4_TEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><alipay><is_success>T</is_success><request><param name=\"trans_create_time\">20160323103315</param><param name=\"identity_code_type\">barcode</param><param name=\"alipay_seller_id\">2088021966645500</param><param name=\"sign_type\">RSA</param><param name=\"trans_amount\">61.87</param><param name=\"trans_name\">PAYMENT_BY_ALIPAY_BARCODE</param><param name=\"partner_trans_id\">1475</param><param name=\"buyer_identity_code\">123456789012345678</param><param name=\"currency\">AUD</param><param name=\"sign\">T0cPCjvrtoOMgMx5kztMXJj1k7BquXSszD0yXK9IoGYt/PwDYK6UUZiMWN41QUpjGZD1uDMKJWhtRMfw7Zwsd5/ieQ3ODB/OMy6FN6zCrztUr4v0rpPvyCRTI9DWR8iVqPay64lT3335AbvqD3wp2zqw97xbQ9e2ykmH/7VVrlQ=</param><param name=\"_input_charset\">UTF-8</param><param name=\"biz_product\">OVERSEAS_MBARCODE_PAY</param><param name=\"service\">alipay.acquire.overseas.spot.pay</param><param name=\"partner\">2088021966645500</param></request><response><alipay><error>INVALID_PARAMETER</error><result_code>FAILED</result_code></alipay></response><sign>D/UTFJt5yh3rxNXSE5botyzpyv9vDe/QbJpLgJ98j3j9HtGcVHpUtPyFr/3ZuVt3VFJ4XI9v41/wqe1qBEeTjffg4hmXOWF1nc8+ePfZNi883Qgl7a4d3hzcXzr9j1lsK33cJeruLEBeQOiu7umd3jPBHdBSBx9qt7DbeLgbtKM=</sign><sign_type>RSA</sign_type></alipay>";
	public static final String RESULT_PAYMENT_UNKNOWN_4_TEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><alipay><is_success>T</is_success><request><param name=\"trans_create_time\">20160525160510</param><param name=\"identity_code_type\">barcode</param><param name=\"alipay_seller_id\">2088021966645500</param><param name=\"sign_type\">RSA</param><param name=\"trans_amount\">61.87</param><param name=\"trans_name\">PAYMENT_BY_ALIPAY_BARCODE</param><param name=\"partner_trans_id\">1475</param><param name=\"buyer_identity_code\">123456789012345678</param><param name=\"currency\">AUD</param><param name=\"sign\">T0cPCjvrtoOMgMx5kztMXJj1k7BquXSszD0yXK9IoGYt/PwDYK6UUZiMWN41QUpjGZD1uDMKJWhtRMfw7Zwsd5/ieQ3ODB/OMy6FN6zCrztUr4v0rpPvyCRTI9DWR8iVqPay64lT3335AbvqD3wp2zqw97xbQ9e2ykmH/7VVrlQ=</param><param name=\"_input_charset\">UTF-8</param><param name=\"biz_product\">OVERSEAS_MBARCODE_PAY</param><param name=\"service\">alipay.acquire.overseas.spot.pay</param><param name=\"partner\">2088021966645500</param></request><response><alipay><result_code>UNKNOW</result_code></alipay></response><sign>D/UTFJt5yh3rxNXSE5botyzpyv9vDe/QbJpLgJ98j3j9HtGcVHpUtPyFr/3ZuVt3VFJ4XI9v41/wqe1qBEeTjffg4hmXOWF1nc8+ePfZNi883Qgl7a4d3hzcXzr9j1lsK33cJeruLEBeQOiu7umd3jPBHdBSBx9qt7DbeLgbtKM=</sign><sign_type>RSA</sign_type></alipay>";
	public static final String RESULT_PAYMENT_FAILEDFAIED_4_TEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><alipay><is_success>F</is_success><error>ILLEGAL_SIGN</error><sign>D/UTFJt5yh3rxNXSE5botyzpyv9vDe/QbJpLgJ98j3j9HtGcVHpUtPyFr/3ZuVt3VFJ4XI9v41/wqe1qBEeTjffg4hmXOWF1nc8+ePfZNi883Qgl7a4d3hzcXzr9j1lsK33cJeruLEBeQOiu7umd3jPBHdBSBx9qt7DbeLgbtKM=</sign><sign_type>RSA</sign_type></alipay>";
}
